#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_watchdog.h"
#include "iot_pwm.h"
#include "hi_pwm.h"
#include "hi_io.h"

#define TASK_GPIO 9
#define INTERVAL_TIME 30
#define TASK_STACK_SIZE 1024
#define TASK_PRIO 25

struct music
{
    uint8_t Note;
    uint8_t Duration;
};

static const uint16_t g_Freqs[] = {
    0,    // 低音   0
    262,  //     1
    294,  //     2
    330,  //     3
    349,  //     4
    392,  //     5
    440,  //     6
    494,  //     7
    415,  // #5
    0,    //
    0,    //
    523,  // 中音11
    587,  //    12
    659,  //    13
    697,  //    14
    784,  //    15
    880,  //    16
    988,  //    17
    831,  // #5
    0,    //
    0,    //
    1046, // 高音21
    1175, //   22
    1318, //   23
    1397, //   24
    1568, //   25
    1760, //   26
    1976, //   27
};        // musical scale

static const struct music g_music[] = 
    {{13,1}, {16,1}, {17,1},
     {21, 2}, {13, 2}, {13, 2}, {21,2}, {17, 2}, {13, 1}, {15, 5},
     {16, 2}, {11, 2}, {11, 2}, {16, 2}, {15, 2}, {14, 1}, {13, 4}, {13, 1},
     {14, 2}, {15, 2}, {16, 2}, {17, 2}, {17, 2}, {21, 1},{ 21, 4}, {21, 1},
     {22,2}, {21, 1}, {22, 3}, {16, 1}, {17, 5}, {0, 1}, {13, 1}, {16, 1}, {17, 1},
     {21, 2}, {13, 2}, {13, 2}, {21, 2},{ 17, 2},{ 13, 1}, {15, 5},
     {16, 2}, {11, 2}, {11, 2}, {16, 2}, {15, 2}, {14, 1}, {13, 4}, {13, 1},
     {14, 2}, {15, 2}, {16, 2}, {17, 2}, {17, 2}, {21, 1}, {21, 4}, {21, 1},
     {17,2}, {21, 1}, {22, 3}, {17, 2}, {16,16}
     };

static void MusicTask()
{
    printf("Ruyuan start!\r\n");

    hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟（40MHz，默认时钟源160MHz）

    for (size_t i = 0; i < sizeof(g_music)/sizeof(g_music[0]); i++)
    {
        uint32_t tune = g_music[i].Note;
        uint16_t freq = g_Freqs[tune];
        uint32_t Delay = g_music[i].Duration;
        IoTPwmStart(0, 50, freq * 10);
        sleep(Delay);
        IoTPwmStop(0);
    }
}

static void ExampleEntry(void)
{
    /*INIT*/
    IoTGpioInit(9);                     // init gpio 9
    IoTGpioSetDir(9, IOT_GPIO_DIR_OUT); // set gpio to be output
    hi_io_set_func(9, 5);               // set function to be pwm
    IoTPwmInit(0);                      // init pwm

    IoTWatchDogDisable();

    osThreadAttr_t attr;
    attr.name = "MusicTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = TASK_STACK_SIZE;
    attr.priority = TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)MusicTask, NULL, &attr) == NULL)
    {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}

SYS_RUN(ExampleEntry);
